/*
 * @Author: lin_zizhuo 2297304135@qq.com
 * @Date: 2023-11-21 18:42:12
 * @LastEditors: lin_zizhuo 2297304135@qq.com
 * @LastEditTime: 2023-11-21 19:32:36
 * @FilePath: /shared_memory/comm.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include "log.hpp"

enum Error
{
    KEY_CREATER_ERROR,
    SHM_GET_ERROR
};

const char* path_name = "/home/lin_zizhuo";
const char* fifo_name = "./mypipe";
enum SIZE
{
    buffer_size = 1024,
};

enum Errno
{
    FIFO_CREATER_ERR = 1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR,
    FIFO_READ_ERR
};

const int proj_id = 0x6666;
//这里共享内存的大小一般选择的是4kb(一个页大小)的整数倍，这是操作系统为了方便定义的
//如果选择的不是4096的整数倍，操作系会给你向上取整，但是你只能使用你规定的那部分内存大小
const int shmSize = 4096;


Log& getLog()
{
    static Log log;
    return log;
}

key_t getIpcKey()
{
    key_t key = ftok(path_name, proj_id);
    if(key < 0)
    {
        getLog().send_message(Fatal, "%s", strerror(errno));
        exit(KEY_CREATER_ERROR);
    }
    getLog().send_message(Info, "key 创建成功: 0x%x", key);
    return key;
}

//传入各种不同的标识，返回得到的共享内存的shmid
int shmGetHelper(int flags)
{
    int shmid = shmget(getIpcKey(), shmSize, flags);
    if(shmid == -1)
    {
        getLog().send_message(Fatal, "共享内存创建或打开失败!");
        exit(SHM_GET_ERROR);
    }
    getLog().send_message(Info, "共享内存创建或寻找成功!");
    return shmid;
}

int shmCreater()
{
    return shmGetHelper(IPC_CREAT | IPC_EXCL | 0666);
}

int shmGeter()
{
    return shmGetHelper(IPC_CREAT);
}

class Init
{
public:
    Init()
    {
        int n = mkfifo(fifo_name, 0664);
        if (n == -1)
        {
            perror("mkfifo");
            exit(FIFO_CREATER_ERR);
        }
        // cout << "mkfifo success!\n";
    }

    ~Init()
    {
        int n = unlink(fifo_name);
        if (n == -1)
        {
            perror("unlink fifo");
            exit(FIFO_DELETE_ERR);
        }
        // cout << "mkfifo delete success!\n";
    }
};